#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> 
#include <stdlib.h>
#include <assert.h>
#include "app_platform/cntl_info.h"
#include "companyao.h"


using namespace erp::company::ao;

CPP_SELF_DEFINE_START
/**
*  请在这里增加自定义的成员变量和函数及其他内容，否则无法合并代码
**/
#include "erp/company/to/companyfilterto_company.h.h"
#include "erp/company/to/companyinfoto_company.h.h"
#include "erp/company/po/businessunitspo_account.h"
#include "erp/company/po/businessunitsfilterpo_account.h"
#include "erp/comm/erp_errno_define.h"
#include "erp/comm/erp_macro_define.h"


using namespace erp::company::po;
using namespace erp::company::ddo;
using namespace erp::company::to;
using namespace erp::comm;
using namespace c2cent::library::wwlog;
using namespace c2cent::library::wtimeelf;
CPP_SELF_DEFINE_END

/**
 *构建函数
 */
CCompanyAo::CCompanyAo(enum DeployMethod method)
{
}

/**
 *析构函数
 */
CCompanyAo::~CCompanyAo()
{
}


/**
 *每一次服务请求时，container都会调用此方法来清空数据
 */
void  CCompanyAo::Reset()
{
}


int  CCompanyAo::Initialize(IUserDefineCntl* pCntl)
{
	int iRet = 0;


	uint32_t dwLogSwitch = WLOG_OPEN | WLOG_KEY_OPEN | WLOG_ERR_OPEN;
		uint32_t dwCanLogRemote = 0;
		uint32_t dwPageSizeLimit = ERP_YUN_PAGESIZE_MIN;
		std::string strLogModule = "ao_company";
		std::string strValidProperty = "0,1,2";

		std::cout << "File:" << __FILE__ << " Complie Date: " << __DATE__ << " "
				<< __TIME__ << std::endl;

		GetUintConfig(LogSwitch);
		GetStringConfig(LogModule);
		GetStringConfig(ValidProperty);
		GetUintConfig(CanLogRemote);
		GetUintConfig(PageSizeLimit);

		s_dwPageSizeLimit = dwPageSizeLimit;

		std::set<std::string> setItem;

		SplitStringIntoSet(strValidProperty.c_str(), ",", setItem);

		for (std::set<std::string>::const_iterator it = setItem.begin();
				it != setItem.end(); it++)
		{
			s_bitsetValidPropertyBit.set(strtoull((*it).c_str(), NULL, 10));
		}

		// 初始化日志
		if (C2C_WWLOG->QuickInitForAPP2(strLogModule.c_str(),B2B2CWW_LOG_APP_FILE_PATH, dwCanLogRemote, dwLogSwitch)!= 0)
		{
			std::cerr << "C2C_WWLOG->QuickInitForAPP2 Failed" << std::endl;
			return -1;
		}
		C2C_WW_LOG("C2C_WWLOG->QuickInitForAPP2 OK!");

	return iRet;
}


/**
 *
 * 添加/修改用户企业信息；传入用户企业SysNo不为0时则进行修改，反之则进行添加；
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param CompanyInfoPo companyInfoPo: 用户企业PO，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CCompanyAo::AddAndUpdateCompanyInfo(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const erp::company::po::CCompanyInfoPo& oCompanyInfoPo,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;

	//TODO:业务代码
	    C2C_WW_LOG("AddAndUpdateCompanyInfo %s OpUin:%u MachineKey:%s Source:%s SceneId:%u", __FUNCTION__,
	    		rCntlInfo.getOperatorUin(), strMachineKey.c_str(), strSource.c_str(), dwSceneId);

	    //打印性能日志的同时进行接口的itil上报
	    //C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&s_oGetEmployee_Group);

	    dwRet = CheckCommPara(rCntlInfo, strMachineKey, strSource, dwSceneId);

	    if(dwRet!=0)
	    {
	    	C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
	    	return dwRet;
	    }

	  /*  dwRet = CheckBusinessUnits(oBusinessUnitsPo);

	    if(dwRet!=0)
	    {
	    	C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
	    	return dwRet;
	    }*/

		erp::company::ddo::CCompanyInfoDdo oCompanyInfoDdo;
		CCompanyInfoPoConvCCompanyInfoDdo::Conv_CCompanyInfoPo_To_CCompanyInfoDdo(oCompanyInfoPo,oCompanyInfoDdo);


		dwRet = m_cCompanyDaoStub4App.AddAndUpdateCompany(
				rCntlInfo,
				strMachineKey,
				strSource,
				dwSceneId,
				oCompanyInfoDdo,
				strInReserve,
				strErrmsg,
				strOutReserve);

		if(dwRet!=0)
		{
		    C2C_WW_LOG_ERR(dwRet,"ModifyBusinessUnits Failed! SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u ErrMsg:%s",
		    		dwSceneId,rCntlInfo.getOperatorUin(), strMachineKey.c_str(), strSource.c_str(), dwSceneId,strErrmsg.c_str());
		    C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
			return dwRet;
		}

	return dwRet;
}

/**
 *
 * 删除用户企业（逻辑）
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param uint64_t companySysNo: 需删除用户企业的SysNo，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CCompanyAo::DeleteCompanyInfo(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				uint64_t ddwCompanySysNo,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}

/**
 *
 * 根据用户企业ID批量获取用户企业信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param Set companySysNo: 需获取的用户企业SysNo，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map errorCode: 获取失败的错误码 	[out]
 *@param Map errorMsg: 获取失败的错误信息 	[out]
 *@param Map companyInfoPo: 获取成功的用户企业信息 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CCompanyAo::GetCompanyInfoByIds(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const std::set<uint64_t >& setCompanySysNo,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::map<uint64_t,uint32_t >& mapErrorCode,
				std::map<uint64_t,std::string >& mapErrorMsg,
				std::map<uint64_t,erp::company::po::CCompanyInfoPo >& mapCompanyInfoPo,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}

/**
 *
 * 根据过滤条件查询用户企业列表信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param CompanyFilterPo filter: 过滤器，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param uint32_t total: 用户企业总数 	[out]
 *@param Vector companyInfoPo: 用户企业列表信息 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CCompanyAo::GetCompanyInfoByFilter(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const erp::company::po::CCompanyFilterPo& oFilter,
				const std::string& strInReserve,
				std::string& strErrmsg,
				uint32_t& dwTotal,
				std::vector<erp::company::po::CCompanyInfoPo >& vecCompanyInfoPo,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}\
uint32_t CCompanyAo::CheckCommPara(
		const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey,
		const std::string& strSource,
		uint32_t dwSceneId)
{
	int32_t iRetCode = 0;

	if(strMachineKey.empty())
	{
		iRetCode=ERR_ERP_COMMON_MACHINEKEY_INVALID;
		C2C_WW_LOG_ERR(iRetCode,"MachineKey Error! MachineKey:%s OpUin:%u  Source:%s SceneId:%u",
				strMachineKey.c_str(),rCntlInfo.getOperatorUin(), strSource.c_str(), dwSceneId);
		return iRetCode;
	}

	if(strSource.empty())
	{
		iRetCode=ERR_ERP_COMMON_SOURCE_INVALID;
		C2C_WW_LOG_ERR(iRetCode,"Source Error! MachineKey:%s OpUin:%u  Source:%s SceneId:%u",
				strMachineKey.c_str(),rCntlInfo.getOperatorUin(), strSource.c_str(), dwSceneId);
		return iRetCode;
	}

	if(dwSceneId==0)
	{
		iRetCode=ERR_ERP_COMMON_SCENEID_INVALID;
		C2C_WW_LOG_ERR(iRetCode,"SceneId Error! MachineKey:%s OpUin:%u  Source:%s SceneId:%u",
				strMachineKey.c_str(),rCntlInfo.getOperatorUin(), strSource.c_str(), dwSceneId);
		return iRetCode;
	}

	return iRetCode;
}
